home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 151-175 / 169 / src / shell / comm1.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  12KB  |  648 lines

  1.  
  2. /*
  3.  * COMM1.C
  4.  *
  5.  * (c)1986 Matthew Dillon     9 October 1986
  6.  *
  7.  *    SLEEP
  8.  *    NUMBER      -handles values as commands, actually a NULL command.
  9.  *    CAT
  10.  *    COMMENT
  11.  *    DIR      -also handles DEVINFO
  12.  *    QUIT      -also handles EXIT
  13.  *    ECHO
  14.  *    SOURCE
  15.  *    CD
  16.  *    MKDIR
  17.  *    MV
  18.  *    RM
  19.  *    HISTORY
  20.  *    MEM
  21.  *    FOREACH
  22.  *    FOREVER
  23.  *
  24.  *    NOTE: SET/UNSET/ALIAS/UNALIAS handled in SET.C
  25.  *
  26.  */
  27.  
  28. #include "shell.h"
  29. #include <stdio.h>
  30.  
  31. extern LOCK *CreateDir(), *CurrentDir(), *ParentDir();
  32. extern LOCK *Lock(), *DupLock();
  33.  
  34. extern long disp_entry();
  35.  
  36. struct FileLock *Clock;
  37.  
  38. do_sleep()
  39. {
  40.     register int i;
  41.  
  42.     if (ac == 2) {
  43.     i = atoi(av[1]);
  44.     while (i > 0) {
  45.         Delay (50*2);
  46.         i -= 2;
  47.         if (CHECKBREAK())
  48.         break;
  49.      }
  50.     }
  51.     return (0);
  52. }
  53.  
  54.  
  55. do_number()
  56. {
  57.     return (0);
  58. }
  59.  
  60. do_cat()
  61. {
  62.     FILE *fi;
  63.     short i;
  64.     char buf[256];
  65.  
  66.     if (ac == 1) {
  67.     while (fgets(buf, 256, stdin)) {
  68.         Write(Cout, buf, strlen(buf));
  69.         if (CHECKBREAK())
  70.         break;
  71.     }
  72.     clearerr(stdin);
  73.     }
  74.     for (i = 1; i < ac; ++i) {
  75.     if (fi = fopen (av[i], "r")) {
  76.         while (fgets (buf, 256, fi)) {
  77.         Write(Cout, buf, strlen(buf));
  78.         if (CHECKBREAK())
  79.             break;
  80.         }
  81.         fclose(fi);
  82.     } else {
  83.         fhprintf (Cerr, "could not open %s\n", av[i]);
  84.     }
  85.     }
  86.     return (0);
  87. }
  88.  
  89. /*
  90.  * comment file string
  91.  */
  92.  
  93. do_comment(str)
  94. char *str;
  95. {
  96.     register char *ptr = next_word(next_word(str));
  97.  
  98.     if (SetComment(av[1], ptr) == 0) {
  99.     perror(av[1]);
  100.     return(1);
  101.     }
  102.     return(0);
  103. }
  104.  
  105. do_dir(garbage, com)
  106. char *garbage;
  107. {
  108.     register struct DPTR      *dp;
  109.     register struct InfoData      *info;
  110.     char *name;
  111.     char br = 0;
  112.     register short i;
  113.     int   stat;
  114.     short longmode = 1;
  115.     short dcomment = 1;
  116.     short avstart = 1;
  117.     register long total = 0;
  118.  
  119.     if (av[1][0] == '-') {
  120.     ++avstart;
  121.     for (i = 1; av[1][i]; ++i) {
  122.         switch(av[1][i]) {
  123.         case 's':
  124.         longmode = 0;
  125.         break;
  126.         case 'l':
  127.         longmode = 1;
  128.         break;
  129.         case 'C':
  130.         dcomment = 0;
  131.         break;
  132.         }
  133.     }
  134.     }
  135.     if (ac == avstart)
  136.     av[ac++] = "";
  137.     for (i = avstart; !br && i < ac; ++i) {
  138.     if ((dp = dopen (av[i], &stat)) == NULL)
  139.         continue;
  140.     if (com < 0) {
  141.         info = (struct InfoData *)AllocMem(sizeof(struct InfoData), MEMF_PUBLIC);
  142.         if (Info (dp->lock, info)) {
  143.         int bpb = info->id_BytesPerBlock;
  144.         fhprintf (Cout, "Unit:%2ld  Errs:%3ld  Bytes: %-7ld Free: %-7ld %%full: %ld\n",
  145.                info->id_UnitNumber,
  146.                info->id_NumSoftErrors,
  147.                bpb * info->id_NumBlocks,
  148.                bpb * (info->id_NumBlocks - info->id_NumBlocksUsed),
  149.                info->id_NumBlocksUsed * 100 / info->id_NumBlocks
  150.         );
  151.         } else {
  152.         perror (av[i]);
  153.         }
  154.         FreeMem (info, sizeof(*info));
  155.     } else {
  156.         if (stat) {
  157.         while (dnext (dp, &name, &stat)) {
  158.             total += disp_entry (dp->fib, longmode, dcomment);
  159.             if (CHECKBREAK()) {
  160.             br = 1;
  161.             break;
  162.             }
  163.         }
  164.         } else {
  165.         total += disp_entry(dp->fib, longmode, dcomment);
  166.         }
  167.     }
  168.     dclose (dp);
  169.     }
  170.     fhprintf (Cout, "TOTAL: %ld\n", total);
  171.     return (0);
  172. }
  173.  
  174. static long
  175. disp_entry(fib, lengthy, comment)
  176. register struct FileInfoBlock *fib;
  177. {
  178.     char str[6];
  179.     char dstr[32];
  180.     register char *dirstr;
  181.  
  182.     str[5] = '\0';
  183.     str[0] = (fib->fib_Protection & FIBF_READ) ? '-' : 'r';
  184.     str[1] = (fib->fib_Protection & FIBF_WRITE) ? '-' : 'w';
  185.     str[2] = (fib->fib_Protection & FIBF_EXECUTE) ? '-' : 'x';
  186.     str[3] = (fib->fib_Protection & FIBF_DELETE) ? '-' : 'd';
  187.     str[4] = (fib->fib_Protection & FIBF_ARCHIVE) ? '-' : 'a';
  188.     dirstr = (fib->fib_DirEntryType < 0) ? "   " : "DIR";
  189.  
  190.     fhprintf (Cout, "%s %6ld %s  %-20s", str, (long)fib->fib_Size,
  191.     dirstr, fib->fib_FileName
  192.     );
  193.     if (lengthy)
  194.     fhprintf (Cout, " %s", datetos(&fib->fib_Date, dstr, "D M Y h:m"));
  195.     if (comment)
  196.     fhprintf (Cout, " %s", fib->fib_Comment);
  197.     fhprintf(Cout, "\n");
  198.     return ((long)fib->fib_Size);
  199. }
  200.  
  201.  
  202. do_quit()
  203. {
  204.     if (Src_stack) {
  205.     Quit = 1;
  206.     return(do_return());
  207.     }
  208.     main_exit (0);
  209. }
  210.  
  211.  
  212. do_echo(str)
  213. char *str;
  214. {
  215.     register char *ptr;
  216.     char nl = 1;
  217.  
  218.     for (ptr = str; *ptr && *ptr != ' '; ++ptr);
  219.     if (*ptr == ' ')
  220.     ++ptr;
  221.     if (av[1] && strcmp (av[1], "-n") == 0) {
  222.     nl = 0;
  223.     ptr += 2;
  224.     if (*ptr == ' ')
  225.         ++ptr;
  226.      }
  227.      Write(Cout, ptr, strlen(ptr));
  228.      if (nl)
  229.      Oputs("");
  230.      return (0);
  231. }
  232.  
  233.  
  234. do_source(str)
  235. char *str;
  236. {
  237.     register FILE *fi;
  238.     register char *buf;
  239.  
  240.     buf = malloc(256);
  241.     if (buf == NULL) {
  242.     Eputs ("no memory");
  243.     goto error;
  244.     }
  245.     if (Src_stack == MAXSRC) {
  246.     Eputs ("Too many source levels");
  247. error:
  248.     if ((long)av[0] == -1)
  249.         UnLock(av[1]);
  250.     return(-1);
  251.     }
  252.     if ((long)av[0] == -1) {
  253.     long oldir = (long)CurrentDir(av[1]);
  254.     fi = fopen("", "r");
  255.     UnLock(CurrentDir(oldir));
  256.     } else {
  257.     fi = fopen (av[1], "r");
  258.     }
  259.     if (fi == NULL) {
  260.     fhprintf(Cerr, "Cannot open %s\n", next_word(str));
  261.     return(-1);
  262.     }
  263.     set_var(LEVEL_SET, V_PASSED, next_word(next_word(str)));
  264.     ++H_stack;
  265.     Src_pos[Src_stack] = 0;
  266.     Src_base[Src_stack] = (long)fi;
  267.     ++Src_stack;
  268.     while (fgets(buf, 256, fi)) {
  269.     register int len = strlen(buf);
  270.     buf[len-1] = 0;             /* remove \n        */
  271.     Src_pos[Src_stack - 1] += len;        /* + (1 + actual length)    */
  272.     if (Verbose)
  273.         Eputs(buf);
  274.     exec_command (buf);
  275.     if (CHECKBREAK())
  276.         break;
  277.     }
  278.     --H_stack;
  279.     --Src_stack;
  280.     unset_level(LEVEL_LABEL + Src_stack);
  281.     unset_var(LEVEL_SET, V_PASSED);
  282.     fclose (fi);
  283.     return (0);
  284. }
  285.  
  286. /*
  287.  * CD
  288.  *
  289.  * CD(str, -1)      -do pwd and display current cd. if str = NULL don't disp.
  290.  * CD(str, 0)       -do CD operation.
  291.  *
  292.  *    standard operation: breakup path by '/'s and process independantly
  293.  *    x:    -reset cwd base
  294.  *    ..    -remove last cwd element
  295.  *    N     -add N or /N to cwd
  296.  */
  297.  
  298. do_cd(str, com)
  299. register char *str;
  300. {
  301.     static char cwd[256];
  302.     register char sc, *ptr;
  303.     char *name;
  304.  
  305.     if (com < 0) {
  306.     register struct FileLock *lock, *newlock;
  307.     register FIB *fib;
  308.     short i, len;
  309.  
  310.     fib = (FIB *)AllocMem(sizeof(FIB), 0);
  311.     Clock = (struct FileLock *)((PROC *)FindTask(0))->pr_CurrentDir;
  312.     if (!Clock)
  313.         CurrentDir(Clock = Lock(":", ACCESS_READ));
  314.     lock = DupLock(Clock);
  315.     cwd[i = 255] = '\0';
  316.     while (lock) {
  317.         newlock = ParentDir(lock);
  318.         Examine(lock, fib);
  319.         name = fib->fib_FileName;
  320.         if (*name == '\0')            /* HACK TO FIX RAM: DISK BUG */
  321.         name = "ram";
  322.         len = strlen(name);
  323.         if (newlock) {
  324.         if (i == 255) {
  325.             i -= len;
  326.             bmov(name, cwd + i, len);
  327.         } else {
  328.             i -= len + 1;
  329.             bmov(name, cwd + i, len);
  330.             cwd[i+len] = '/';
  331.         }
  332.         } else {
  333.         i -= len + 1;
  334.         bmov(name, cwd + i, len);
  335.         cwd[i+len] = ':';
  336.         }
  337.         UnLock(lock);
  338.         lock = newlock;
  339.     }
  340.     FreeMem(fib, sizeof(FIB));
  341.     bmov(cwd + i, cwd, 256 - i);
  342.     if (str)
  343.         Oputs(cwd);
  344.     goto cdset;
  345.     }
  346.     str = next_word(str);
  347.     if (*str == '\0')
  348.     Oputs(cwd);
  349.     str[strlen(str)+1] = '\0';          /* add second \0 on end */
  350.     while (*str) {
  351.     for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
  352.     switch (*ptr) {
  353.     case ':':
  354.         sc = ptr[1];
  355.         ptr[1] = '\0';
  356.         if (attempt_cd(str))
  357.         strcpy(cwd, str);
  358.         ptr[1] = sc;
  359.         break;
  360.     case '\0':
  361.     case '/':
  362.         *ptr = '\0';
  363.         if (strcmp(str, "..") == 0 || str == ptr)
  364.         str = "/";
  365.         if (*str && attempt_cd(str)) {
  366.         if (*str == '/') {
  367.             rmlast(cwd);
  368.         } else {
  369.             if (cwd[0] == 0 || cwd[strlen(cwd)-1] != ':')
  370.             strcat(cwd, "/");
  371.             strcat(cwd, str);
  372.         }
  373.         }
  374.         break;
  375.     }
  376.     str = ptr + 1;
  377.     }
  378. cdset:
  379.     set_var(LEVEL_SET, V_CWD, cwd);
  380.     return (0);
  381. }
  382.  
  383. attempt_cd(str)
  384. char *str;
  385. {
  386.     register struct FileLock *oldlock, *filelock;
  387.  
  388.     if (filelock = Lock(str, ACCESS_READ)) {
  389.     if (isdir(str)) {
  390.         UnLock(CurrentDir(filelock));
  391.         Clock = filelock;
  392.         return(1);
  393.     }
  394.     UnLock(filelock);
  395.     ierror(str, 212);
  396.     } else {
  397.     ierror(str, 205);
  398.     }
  399.     return (0);
  400. }
  401.  
  402.  
  403. /*
  404.  * remove last component. Start at end and work backwards until reach
  405.  * a '/'
  406.  */
  407.  
  408. rmlast(str)
  409. char *str;
  410. {
  411.     register char *ptr = str + strlen(str) - 1;
  412.  
  413.     while (ptr != str && *ptr != '/' && *ptr != ':')
  414.     --ptr;
  415.     if (*ptr != ':')
  416.     ptr[0] = '\0';
  417.     else
  418.     ptr[1] = '\0';
  419. }
  420.  
  421.  
  422. do_mkdir()
  423. {
  424.     register short i;
  425.     register struct FileLock *lock;
  426.  
  427.     for (i = 1; i < ac; ++i) {
  428.     if (lock = CreateDir (av[i])) {
  429.         UnLock (lock);
  430.         continue;
  431.     }
  432.     perror (av[i]);
  433.     }
  434.     return (0);
  435. }
  436.  
  437. /*
  438.  *  MV file1 file2
  439.  *  MV file1 file2....fileN dir
  440.  */
  441.  
  442. do_mv()
  443. {
  444.     char dest[256];
  445.     register short i, len;
  446.     register char *str;
  447.  
  448.     --ac;
  449.     if (isdir(av[ac])) {
  450.     len = strlen(av[ac]);
  451.     for (i = 1; i < ac; ++i) {
  452.         str = av[i] + strlen(av[i]) - 1;
  453.         while (str >= av[i] && *str != '/' && *str != ':')
  454.         --str;
  455.         ++str;
  456.         if (*str == 0) {
  457.         ierror(av[i], 508);
  458.         return (-1);
  459.         }
  460.         strcpy(dest, av[ac]);
  461.         if (dest[0] && dest[len-1] != ':' && dest[len-1] != '/')
  462.         strcat(dest, "/");
  463.         strcat(dest, str);
  464.         if (Rename(av[i], dest) == 0)
  465.         break;
  466.     }
  467.     if (i == ac)
  468.         return (1);
  469.     } else {
  470.     i = 1;
  471.     if (ac != 2) {
  472.         ierror("mv:", 507);
  473.         return (-1);
  474.     }
  475.     if (Rename (av[1], av[2]))
  476.         return (0);
  477.     }
  478.     perror (av[i]);
  479.     return (-1);
  480. }
  481.  
  482.  
  483. do_rm()
  484. {
  485.     register short i, recur;
  486.  
  487.     recur = (strncmp(av[1], "-r", 2)) ? 0 : 1;
  488.  
  489.     for (i = 1 + recur; i < ac; ++i) {
  490.     if (isdir(av[i]) && recur)
  491.         rmdir(av[i]);
  492.     if (!DeleteFile(av[i]))
  493.         perror(av[i]);
  494.     }
  495.     return (0);
  496. }
  497.  
  498. rmdir(name)
  499. char *name;
  500. {
  501.     register LOCK *lock, *cwd;
  502.     register FIB *fib;
  503.     register char *buf;
  504.  
  505.     buf = (char *)AllocMem(256, 0);
  506.     fib = (FIB *)AllocMem(sizeof(FIB), 0);
  507.  
  508.     if (lock = Lock(name, ACCESS_READ)) {
  509.     cwd = CurrentDir(lock);
  510.     if (Examine(lock, fib)) {
  511.         buf[0] = 0;
  512.         while (ExNext(lock, fib)) {
  513.         if (isdir(fib->fib_FileName))
  514.             rmdir(fib->fib_FileName);
  515.         if (buf[0]) {
  516.             if (!DeleteFile(buf))
  517.             perror(buf);
  518.         }
  519.         strcpy(buf, fib->fib_FileName);
  520.         }
  521.         if (buf[0]) {
  522.         if (!DeleteFile(buf))
  523.             perror(buf);
  524.         }
  525.     }
  526.     UnLock(CurrentDir(cwd));
  527.     } else {
  528.     perror(name);
  529.     }
  530.     FreeMem(fib, sizeof(FIB));
  531.     FreeMem(buf, 256);
  532. }
  533.  
  534.  
  535. do_history()
  536. {
  537.     register struct HIST *hist;
  538.     register short i = H_tail_base;
  539.     register short len = (av[1]) ? strlen(av[1]) : 0;
  540.  
  541.     for (hist = H_tail; hist; hist = hist->prev) {
  542.     if (len == 0 || strncmp(av[1], hist->line, len) == 0) {
  543.         fhprintf (Cout, "%3ld ", i);
  544.         Oputs (hist->line);
  545.     }
  546.     ++i;
  547.     if (CHECKBREAK())
  548.         break;
  549.     }
  550.     return (0);
  551. }
  552.  
  553.  
  554. do_mem()
  555. {
  556.     register long cfree, ffree;
  557.     extern long AvailMem();
  558.  
  559.     Forbid();
  560.     cfree = AvailMem (MEMF_CHIP);
  561.     ffree = AvailMem (MEMF_FAST);
  562.     Permit();
  563.  
  564.     if (ffree)
  565.     fhprintf (Cout, "FAST memory:%10ld\n", ffree);
  566.     fhprintf (Cout, "CHIP memory:%10ld\n", cfree);
  567.     fhprintf (Cout, "Total -----:%5ld K\n", (ffree + cfree) >> 10);
  568.     return (0);
  569. }
  570.  
  571. /*
  572.  * foreach var_name  ( str str str str... str ) commands
  573.  * spacing is important (unfortunetly)
  574.  *
  575.  * ac=0    1 2 3 4 5 6 7
  576.  * foreach i ( a b c ) echo $i
  577.  * foreach i ( *.c )   "echo -n "file ->";echo $i"
  578.  */
  579.  
  580. do_foreach()
  581. {
  582.     register short i, cstart, cend, old;
  583.     register char *cstr, *vname, *ptr, *scr, *args;
  584.  
  585.     cstart = i = (*av[2] == '(') ? 3 : 2;
  586.     while (i < ac) {
  587.     if (*av[i] == ')')
  588.         break;
  589.     ++i;
  590.     }
  591.     if (i == ac) {
  592.     Eputs ("')' expected");
  593.     return (-1);
  594.     }
  595.     ++H_stack;
  596.     cend = i;
  597.     vname = strcpy(malloc(strlen(av[1])+1), av[1]);
  598.     cstr = compile_av (av, cend + 1, ac);
  599.     ptr = args = compile_av (av, cstart, cend);
  600.     while (*ptr) {
  601.     while (*ptr == ' ' || *ptr == 9)
  602.         ++ptr;
  603.     scr = ptr;
  604.     if (*scr == '\0')
  605.         break;
  606.     while (*ptr && *ptr != ' ' && *ptr != 9)
  607.         ++ptr;
  608.     old = *ptr;
  609.     *ptr = '\0';
  610.     set_var (LEVEL_SET, vname, scr);
  611.     if (CHECKBREAK())
  612.         break;
  613.     exec_command (cstr);
  614.     *ptr = old;
  615.     }
  616.     --H_stack;
  617.     free (args);
  618.     free (cstr);
  619.     unset_var (LEVEL_SET, vname);
  620.     free (vname);
  621.     return (0);
  622. }
  623.  
  624.  
  625. do_forever(str)
  626. register char *str;
  627. {
  628.     long rcode = 0;
  629.     register char *ptr = next_word(str);
  630.  
  631.     ++H_stack;
  632.     for (;;) {
  633.     if (CHECKBREAK()) {
  634.         rcode = 20;
  635.         break;
  636.     }
  637.     if (exec_command (ptr) < 0) {
  638.         str = get_var(LEVEL_SET, V_LASTERR);
  639.         rcode = (str) ? atoi(str) : 20;
  640.         break;
  641.     }
  642.     }
  643.     --H_stack;
  644.     return (rcode);
  645. }
  646.  
  647.  
  648.